<?php

defined('IN_XLP') or die('Access Denied');

/*
 * 2015-02-04 支付接口升级
 * 微信统一支付接口 包括JSAPI，NATIVE，APP
 * 文档地址：http://mch.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1
 */

class weixinRedpack {

    //统一下单地址
    const HONGBAO_URL = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';

    //交易类型
    //微信基本参数
    private $appid;
    private $mch_id;    //原partner_id
    private $partner_key;
    private $paysign_key;
    private $debug;
    //支付通知URL
    private $notify_url;
    //运行时间
    private $runtime;

    public function __construct($p = array()) {
        $this->notify_url = U('wxpay/notify/index');
        $this->runtime = date('Y-m-d H:i:s', TIME);

        $this->appid = isset($p['appid']) ? $p['appid'] : '';
        $this->mch_id = isset($p['partner_id']) ? $p['partner_id'] : '';
        $this->partner_key = isset($p['partner_key']) ? $p['partner_key'] : '';
        $this->paysign_key = isset($p['paysign_key']) ? $p['paysign_key'] : '';
        $this->debug = false;
        if (!($this->appid && $this->mch_id && $this->partner_key && $this->paysign_key)) {
            $userInfo = F('weixin/setting');
            if (isHave($userInfo['user_info']['wx_AppId']) && isHave($userInfo['user_info']['wx_PartnerId']) && isHave($userInfo['user_info']['wx_PartnerKey']) && isHave($userInfo['user_info']['wx_PaySignKey'])) {
                //设置微信基本参数
                $this->appid = $userInfo['user_info']['wx_AppId'];
                $this->mch_id = $userInfo['user_info']['wx_PartnerId'];
                $this->partner_key = $userInfo['user_info']['wx_PartnerKey'];
                $this->paysign_key = $userInfo['user_info']['wx_PaySignKey'];
            } else {
                throw new Exception($this->runtime . 'Error:请设置好所有的微信参数');
            }
        }
    }

    /**
     * 发红包
     * 
     * @param  array  $order_params 订单各类参数
     * @param  int    $type         交易类型
     * @return
     */
    public function send($info, $debug = false) {
        $redpackarr['nonce_str'] = getRandStr();
        $redpackarr['mch_billno'] = $this->mch_id . date('YmdHis') . rand(1000, 9999);
        $redpackarr['mch_id'] = $this->mch_id;
        $redpackarr['wxappid'] = $this->appid;
        $redpackarr['nick_name'] = $info['send_name'];
        $redpackarr['send_name'] = $info['send_name'];
        $redpackarr['re_openid'] = $info['re_openid'];
        $redpackarr['total_amount'] = $info['money'];
        $redpackarr['min_value'] = $info['money'];
        $redpackarr['max_value'] = $info['money'];
        $redpackarr['total_num'] = $info['num'];
        $redpackarr['wishing'] = $info['wishing'];
        $redpackarr['client_ip'] = $_SERVER['REMOTE_ADDR'];
        $redpackarr['act_name'] = $info['act_name'];
        $redpackarr['remark'] = $info['wishing'];
        $redpackarr['sign'] = $this->getMD5Sign($redpackarr);
        $xml = $this->arrayToXml($redpackarr);
        $data = $this->curl_post_ssl(self::HONGBAO_URL, $xml);
        //$data = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[发放成功.]]></return_msg><result_code><![CDATA[SUCCESS]]></result_code><err_code><![CDATA[0]]></err_code><err_code_des><![CDATA[发放成功.]]></err_code_des><mch_billno><![CDATA[10017210201502051643554556]]></mch_billno><mch_id>10017210</mch_id><wxappid><![CDATA[wxbe2fdc3caaab54be]]></wxappid><re_openid><![CDATA[onqqijg7-Pk7y572JV9PsdBp0aW4]]></re_openid><total_amount>100</total_amount></xml>';
        if (!$data) {
            saveLog('weixin/redpackError', '接口通讯失败');
            return false;
        }
        $result = (array) simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);

        if ($debug) {
            saveLog('weixin/redpackLog', array('data' => $redpackarr, 'send' => $xml, 'result' => $data));
            return false;
        }
        if (!isset($result['err_code'])) {
            saveLog('weixin/redpackError', array('data' => $redpackarr, 'send' => $xml, 'result' => $data));
            return false;
        }
        if ($result['err_code'] != '0' || $result['return_code'] == 'FAIL') {
            saveLog('weixin/redpackError', array('data' => $redpackarr, 'send' => $xml, 'result' => $data));
            return false;
        } else {
//            saveLog('weixin/redpackOk', array('data' => $redpackarr, 'send' => $xml, 'result' => $data));
            return true;
        }
    }

    /*
     * 参数签名
     */

    private function getMD5Sign($array = array()) {
        //空值不签名
        ksort($array);
        $str = '';
        foreach ($array as $k => $v) {
            if ($v) {
                $str .= $k . '=' . $v . '&';
            }
        }
        $key = $this->partner_key;
        $signStr = $str . 'key=' . $key;
        return strtoupper(md5($signStr));
    }

    public function arrayToXml($arr) {
        $xml = '<xml>';
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml.='<' . $key . '>' . $val . '</' . $key . '>';
            } else {
                $xml.='<' . $key . '><![CDATA[' . $val . ']]></' . $key . '>';
            }
        }
        $xml.='</xml>';
        return $xml;
    }

    public function curl_post_ssl($url, $vars, $second = 30, $aHeader = array()) {
        $ch = curl_init();
        //超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //这里设置代理，如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        //以下两种方式需选择一种
        //第一种方法，cert 与 key 分别属于两个.pem文件
        //curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/apiclient_cert.pem');
        //curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/apiclient_key.pem');
        curl_setopt($ch, CURLOPT_SSLCERT, '/www/cert/apiclient_cert.pem');
        curl_setopt($ch, CURLOPT_SSLKEY, '/www/cert/apiclient_key.pem');
        curl_setopt($ch, CURLOPT_CAINFO, '/www/cert/rootca.pem');

        //第二种方式，两个文件合成一个.pem文件
        //curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');

        if (count($aHeader) >= 1) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        }

        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
        $data = curl_exec($ch);
        if (curl_errno($ch)) {
            saveLog('https/error', 'Curl Error:url:' . $url . ' ,info:' . curl_error($ch));
            $data = null;
        }
        curl_close($ch);
        return $data;
    }

}
